#pragma once
#include <map>

#include "GameTypedefs.h"
#include "PhysicsObject.h"
#include "StateMachine.h"


/**
=====================================
Base Entity for any object in the game
=====================================
*/
class BaseEntity
{
public:
    BaseEntity(void);

    /** This Ents unique ID */
    type_id  GetID() const { return m_id; };

    /** This Ent is Active */
    bool IsActive() const { return m_active; };
    /** Set activity */
    void SetActive(bool b) { m_active = b; };

    /** Remove the ent */
    bool CanRemove() const { return m_remove; };
    /** Set the remove flag */
    void SetRemove(bool r) { m_remove = r; };

    /** Set the name */
    void SetName( const std::string &s) { m_name = s; };
    /** Get the name */
    std::string GetName() const { return m_name; };

    /** Add a state to this entity */
    void AddState( State_t state, State* s) { m_states[ state ] = s; };

    /** Set the active state */
    void SetState(State_t state) { m_stateMachine.ChangeState( m_states[state] ); };
    /** Get the current state */
    State_t GetState() { return m_stateMachine.GetCurrentState() ? m_stateMachine.GetCurrentState()->GetState() : DEFAULT; };

    /** Set the Position */
    void SetPosition( const MVector3f &p ) { m_physObj.SetPosition( p ); };
    /** Get the Position */
    MVector3f GetPosition() { m_physObj.GetPosition(); };

    /** Test if this is a player */
    virtual bool IsPlayer() const { return false; };

    /** Update this entity */
    virtual void Update( float dt ) {};
    /** Collide with another entity */
    virtual void Touch( BaseEntity* other ) {};

private:
    static type_id      ID_TRACKER;         // assign entities a unique ID
    type_id             m_id;               // reference to the objects id, which is given by ID_TRACKER
    bool                m_active;           // An active ent is one that 'ticks' in the world, an inactive doesn't update
    bool                m_remove;           // flag for removal and deletion
    std::string         m_name;             // The name of this entity
    PhysicsObject       m_physObj;          // to collision of this entity

    StateMachine        m_stateMachine;     // This entities tracking system for states

    typedef std::map< State_t , State* > type_States;
    type_States         m_states;           // List of States


public:
    virtual ~BaseEntity(void);
};
